<?php

/**
 * CelebrioMail PeopleManagement
 *
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    PeopleManagement
 */
namespace ApplicationsModule\PeopleModule;


use Nette\Object;
use Nette\String;
use Nette\Environment;
use Celebrio\Core\ServiceProvider;
use Celebrio\Modules;
use Celebrio\Util\CacheName;

use \Albireo\OAuth\OAuthClient;

use \ApplicationsModule\PeopleModule\Person;

use \dibi;

use \FacebookApiException;

https://graph.facebook.com/oauth/access_token?client_id=133331463420857&redirect_uri=http://localhost/test.php&client_secret=f7037087ff585f21be348bdb95353aec&code=AQDGlRMacYHSS97n3l6cuIxBqTeKSOqEENNRcYz7E33WtuN-rjYuN9YSrWGHyvtmzo__xcmuRrIzQTc8t5on9gcijYipRIdSdA-WKgXMY8AGSvzltbFZ8nePT7oBiv9hPYK-DENdoxebGJw5J4q462teEjY7uszWW6PCNfBL0DqJ2RKj7Av5MULsMsp5F1lzcUg

/**
 * 
 * @author pavel
 */
class Facebook extends DummyContactService implements IContactService {

    const FACEBOOK = "facebook";

    /** @var \Facebook */
    private $facebook_sdk;

    /** @var \Nette\Caching\Cache */
    private $cache;

    /** @var int */
    private $limit = 50;

    // archive call - the first one which worked. however, it still sux
    // $url = "https://graph.facebook.com/search?access_token=$access_token&q="
    //        . urlencode($name) . "&type=$type&limit=$limit"; // default limit is probably 25

    public function __construct() {
        $oAuthClient = new OAuthClient(OAuthClient::FB);
        $credentials = $oAuthClient->getCredentials();
        $appInfo = array(
          'appId'  => $credentials["key"],
          'secret' => $credentials["secret"],
        );

        $this->facebook_sdk = new \Facebook($appInfo);
        $this->facebook_sdk->setAccessToken($credentials["walterwego"]);

        $this->cache = CacheName::generate($this);
    }

    
    // ----------------------------------------------------------------------------------------------------------//

    static function getServiceName() {
        return self::FACEBOOK;
    }

    static function providedRows(array $exclude = array()) {
        return array(
            array("db" => "uid", "display" => false, "protected" => false, "unique" => true),
            array("db" => "fb_pass", "display" => false, "protected" => true)
        );
    }

    /**
     * @todo this could be implemented asynchronously after the response is sent
     *
     * @throws \Exception
     * @param Person $person
     * @return void
     */
    public function onCreatePerson(Person $person)
    {
        parent::onCreatePerson($person);
        $person_info = $person->getAdditionalInfo();

        if (isset($person_info["uid"][0])) {
            $uid = $person_info["uid"][0];
            $access_token_row = dibi::select(array("access_token"))
                    ->from("fb_users_approved")
                    ->where(array("uid" => $uid))
                    ->fetch();

            $generic_access_token = $this->facebook_sdk->getAccessToken();
            if ($access_token_row)
            {
                $this->facebook_sdk->setAccessToken($access_token_row["access_token"]);
            }

            try
            {
                $person_fb_info = $this->facebook_sdk->api("/$uid");
            }
            catch (FacebookApiException $e)
            {
                if (String::startsWith($e->getMessage(), "Error validating access token"))
                {
                    // the user has revoked the access, use geenric access token
                    $this->facebook_sdk->setAccessToken($generic_access_token);
                    dibi::delete("fb_users_approved")->where(array("uid" => $uid))->execute();
                    $person_fb_info = $this->facebook_sdk->api("/$uid");
                }
                else
                {
                    throw $e;
                }
            }


            if (isset($person_fb_info["email"]))
            {
                $cs = ServiceProvider::getAllServices(Modules::CONTACTS);
                foreach($cs as $contact_service)
                {
                    if ($contact_service::providesMail()) {
                        $contact_service->addMail($person->getId(), $person_fb_info["email"]);
                        break;
                    }
                }

            }
        }
    }

    public function search($info) {
        $name = urlencode(trim($info["first_name_person"] . " " . $info["last_name_person"]));
        $users = $this->facebook_sdk->api("/search?q=$name&type=user&limit={$this->limit}");

        if (isset($users["data"]))
        {
            $people_found = array();
            foreach ($users["data"] as $user)
            {
                $name = explode(" ", $user["name"], 2);
                $uid = $user["id"];
                $person = new Person($name[0], $name[1], "http://graph.facebook.com/$uid/picture?type=large");
                $person->addToAdditionalInfo("uid", $uid);
                $people_found[] = $person;
            }

        }
        else
        {
            throw new \Exception("Erroneous data received from facebook.");
        }
        
        return $people_found;

    }

}